package com.laboratory.dom4j.xml.sax;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * SAX解析XML文件
 */
public class SaxTest3 {
    public static void main(String[] args) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();

        SAXParser parser = factory.newSAXParser();
        MyHandler3 myHandler3 = new MyHandler3();
        parser.parse(new File("src//main//java//com//laboratory//dom4j//xml//student.xml"), myHandler3);
        List<Student> studentList = myHandler3.getStudentList();
        System.out.println("studentList = " + studentList);
    }
}


class MyHandler3 extends DefaultHandler {
    private Stack<String> stack ;

    private Student student;
    private List<Student> list;

    private Locator locator;


    @Override
    public void startDocument() throws SAXException {
        list = new ArrayList<>();
        student = null;
        stack = new Stack<String>();
    }

    /*
     uri: 命名空间
     localName: 不带命名空间的标签前缀名
     qName: 带命名空间的标签前缀名
     attributes: 属性集合
      */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {
        stack.push(qName);
        if ("学生".equals(qName)) {
            student = new Student();
            student.setId(Integer.valueOf(attributes.getValue("学号")));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        String tag = stack.peek();
        if (tag != null && student != null) {
            String value = new String(ch, start, length);
            if ("姓名".equals(tag)) {
                student.setName(value);
            } else if ("性别".equals(tag)) {
                student.setGendaer(value);
            } else if ("年龄".equals(tag)) {
                student.setAge(Integer.valueOf(value));
            }
        }
    }

    /*
     uri: 命名空间
     localName: 不带命名空间的标签前缀名
     qName: 带命名空间的标签前缀名
     attributes: 属性集合
      */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        stack.pop(); //表示该元素已经解析完毕，需要从栈中弹出
        if ("学生".equals(qName)) {
            list.add(student);
            student = null;
        }

    }

    public List<Student> getStudentList() {
        return list;
    }

    public void warning(SAXParseException e) throws SAXException {
        System.out.println("Warning occurred: \n");
        System.out.println("Location Info: " + locatorInfo());
        e.printStackTrace(System.out);
    }


    public void error(SAXParseException e) throws SAXException {
        System.out.println("Error occurred: \n");
        System.out.println("Location Info: " + locatorInfo());
        e.printStackTrace(System.out);
    }


    public void fatalError(SAXParseException e) throws SAXException {
        System.out.println("Fatal Error occurred: \n");
        System.out.println("Location Info: " + locatorInfo());
        e.printStackTrace(System.out);
        throw e;
    }

    @Override
    public void setDocumentLocator(Locator locator) {
        super.setDocumentLocator(locator);
        this.locator = locator;
    }

    private String locatorInfo() {
        return "resource: " + locator.getSystemId() + ", Locator Info: [" + locator.getLineNumber() + ", " + locator.getColumnNumber() + "]";
    }
}

class Student {
    private int id;
    private String name;
    private String gendaer;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGendaer() {
        return gendaer;
    }

    public void setGendaer(String gendaer) {
        this.gendaer = gendaer;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student(int id, String name, String gendaer, int age) {
        this.id = id;
        this.name = name;
        this.gendaer = gendaer;
        this.age = age;
    }

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gendaer='" + gendaer + '\'' +
                ", age=" + age +
                '}';
    }
}























